<template>
  <div class="editor-container">
    <!-- 左侧音符菜单 -->
    <MakeScore @click-number="insertNoteSymbol" />

    <!-- 右侧编辑区域 -->
    <div class="editor-area">
      <!-- 工具栏 -->
      <div class="top-toolbar">
        <el-button-group>
          <el-button size="small" @click="undo" :disabled="state.historyIndex <= 0">撤销</el-button>
          <el-button size="small" @click="redo" :disabled="state.historyIndex >= state.history.length - 1">
            重做
          </el-button>
        </el-button-group>

        <el-button-group>
          <el-button size="small" @click="copySelection">复制</el-button>
          <el-button size="small" @click="pasteFromClipboard">粘贴</el-button>
        </el-button-group>

        <el-button size="small" @click="addLyricLine">添加歌词行</el-button>

        <!-- 对齐方式切换 -->
        <el-button-group>
          <el-button
            size="small"
            :type="alignMode === 'left' ? 'primary' : 'default'"
            @click="setAlignMode('left')"
            title="左对齐"
          >
            <i class="el-icon-align-left"></i>
            左对齐
          </el-button>
          <el-button
            size="small"
            :type="alignMode === 'justify' ? 'primary' : 'default'"
            @click="setAlignMode('justify')"
            title="两端对齐"
          >
            <i class="el-icon-full-screen"></i>
            两端对齐
          </el-button>
        </el-button-group>

        <el-button-group>
          <el-button size="small" @click="addNewPage">新增页</el-button>
          <el-button
            size="small"
            @click="removeCurrentPageIfEmpty"
            :disabled="currentLine.page === 0 || !isCurrentPageEmpty()"
          >
            删除空页
          </el-button>
        </el-button-group>
      </div>

      <!-- 可滚动的编辑容器 -->
      <div class="editor-scroll-container" @wheel="handleWheel" ref="scrollContainerRef">
        <div class="editor-zoom-container" :style="{ transform: `scale(${zoom / 100})` }">
          <!-- A4纸张页面 -->
          <div v-for="(page, pageIndex) in pages" :key="'page-' + pageIndex" class="page-container">
            <!-- 每一页的音符行循环 -->
              <div
                v-for="(line, lineIndex) in page.lines"
              :key="'line-' + pageIndex + '-' + lineIndex"
              class="line-container"
              >
                <!-- 音符区域 -->
                <div
                class="note-area"
                :class="{
                  active: isNoteAreaActive(pageIndex, lineIndex),
                  'no-text-input': true,
                }"
                  :data-page="pageIndex"
                  :data-line="lineIndex"
                tabindex="0"
                ref="noteAreas"
                @focus="handleNoteFocus($event, pageIndex, lineIndex)"
                @blur="handleNoteBlur"
                @click="handleNoteClick($event, pageIndex, lineIndex)"
                @keydown="handleKeyDown($event, pageIndex, lineIndex)"
              >
                <!-- 音符渲染区域 -->
                <div class="notes-container" :class="{ 'notes-justify': alignMode === 'justify' }">
                  <!-- 虚拟光标显示 - 在行首位置 -->
                  <div
                    v-if="
                      cursorPosition.page === pageIndex &&
                      cursorPosition.line === lineIndex &&
                      cursorPosition.noteIndex === -1 &&
                      cursorPosition.visible
                    "
                    class="virtual-cursor"
                ></div>

                  <!-- 音符渲染 -->
                  <template
                    v-for="(note, noteIndex) in line.notes"
                    :key="'note-' + pageIndex + '-' + lineIndex + '-' + noteIndex"
                  >
                    <span
                      class="note-span"
                      :class="{ selected: isNoteSelected(pageIndex, lineIndex, noteIndex) }"
                      :data-index="noteIndex"
                      v-html="note.html"
                    ></span>

                    <!-- 音符后的虚拟光标 -->
                    <div
                      v-if="
                        cursorPosition.page === pageIndex &&
                        cursorPosition.line === lineIndex &&
                        cursorPosition.noteIndex === noteIndex &&
                        cursorPosition.visible
                      "
                      class="virtual-cursor"
                    ></div>
                  </template>

                  <!-- 空白提示 -->
                  <div v-if="line.notes.length === 0" class="empty-placeholder">点击此处添加音符</div>
                </div>

                <!-- 歌词显示和编辑区域 -->
                <div v-if="line.lyric !== undefined" class="lyric-container" @click.stop>
                  <!-- 显示模式：显示歌词文本，点击可进入编辑模式 -->
                  <div
                    v-if="!line.lyricEditing"
                    class="lyric-display-container"
                    :class="{ 'lyric-justify': alignMode === 'justify' }"
                  >
                    <div class="lyric-display" @click="enterLyricEditMode(pageIndex, lineIndex, $event)">
                      {{ line.lyric || '点击编辑歌词' }}
                    </div>
                    <button
                      class="lyric-delete-btn"
                      @click="removeLyric(pageIndex, lineIndex, $event)"
                      title="删除歌词"
                    >
                      ×
                    </button>
                  </div>

                  <!-- 编辑模式：使用el-input替代普通input -->
                  <div class="lyric-input-container">
                    <el-input
                      v-if="line.lyricEditing"
                      v-model="line.lyric"
                  :data-page="pageIndex"
                  :data-line="lineIndex"
                      placeholder="输入歌词后按回车保存"
                      @blur="handleLyricInputBlur($event, pageIndex, lineIndex, line.lyricEditing)"
                      @keydown="handleLyricInputKeydown($event, pageIndex, lineIndex)"
                      size="default"
                  @click.stop
                    />
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 底部状态栏 -->
      <div class="bottom-status-bar">
        <div class="page-info">第 {{ currentLine.page + 1 }} 页 | 行 {{ currentLine.line + 1 }}</div>
        <!-- 缩放控制按钮 -->
        <el-button-group>
          <el-button size="small" @click="zoomOut" title="缩小">-</el-button>
          <el-button size="small">{{ zoom }}%</el-button>
          <el-button size="small" @click="zoomIn" title="放大">+</el-button>
          <el-button style="margin-left: 10px" size="small" @click="resetZoom" title="重置缩放">重置</el-button>
        </el-button-group>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick, watch, onUnmounted } from 'vue';
import type { Ref } from 'vue';
import MakeScore from './makeScore.vue';

// 缩放百分比
const zoom = ref(100);
const scrollContainerRef = ref<HTMLElement | null>(null);

// 缩放控制函数
const zoomIn = () => {
  // 每次放大5%，最大150%
  zoom.value = Math.min(150, zoom.value + 5);
  saveHistory();
};

const zoomOut = () => {
  // 每次缩小5%，最小50%
  zoom.value = Math.max(50, zoom.value - 5);
  saveHistory();
};

const resetZoom = () => {
  // 重置为100%
  zoom.value = 100;
  saveHistory();
};

// 音符对齐模式: 'left' 或 'justify'
const alignMode = ref<'left' | 'justify'>('left');

// 设置对齐模式
const setAlignMode = (mode: 'left' | 'justify') => {
  alignMode.value = mode;
  // 保存历史记录，使得对齐模式可以撤销恢复
  saveHistory();
};

// 编辑器相关引用
const pageRefs = ref<HTMLElement[]>([]);
const currentLine = ref({ page: 0, line: 0 });

// 剪贴板数据
const clipboardData = ref<MusicNote[]>([]);

// 记录点击的音符区域，确保正确的光标位置
const activeNoteArea = ref<HTMLElement | null>(null);

// 光标闪烁相关
const showCursor = ref(true);
const cursorBlinkInterval = ref<number | null>(null);

// 音符数据模型
interface MusicNote {
  name: string; // 音符类型名称
  value: string; // 音符显示的值
  type?: string; // 可选的额外类型信息
  html?: string; // 渲染用HTML内容
}

// 页面数据模型
interface MusicLine {
  notes: MusicNote[]; // 使用数组替代原来的content字符串
  lyric?: string;
  lyricEditing?: boolean;
}

interface Page {
  lines: MusicLine[];
}

// 页面数据
const pages = ref<Page[]>([
  {
    lines: [
      {
        notes: [],
        lyric: '', // 改为空字符串而不是undefined
        lyricEditing: false,
      },
    ],
  },
]);

// 虚拟光标位置
const cursorPosition = ref({
  page: 0,
  line: 0,
  noteIndex: -1, // -1表示在行首，其他值表示在该音符后面
  visible: true,
});

// 选择范围
const selection = ref({
  active: false,
  startPage: 0,
  startLine: 0,
  startNote: -1,
  endPage: 0,
  endLine: 0,
  endNote: -1,
});

// 响应式数据
const state = reactive({
  history: [] as string[],
  historyIndex: -1,
});

// 是否阻止历史记录保存
const preventHistorySave = ref(false);

// 辅助函数判断音符区域是否激活
const isNoteAreaActive = (pageIndex: number, lineIndex: number) => {
  return currentLine.value.page === pageIndex && currentLine.value.line === lineIndex;
};

// 判断音符是否被选中
const isNoteSelected = (pageIndex: number, lineIndex: number, noteIndex: number) => {
  if (!selection.value.active) return false;

  // 获取选择范围的起始和结束位置
  const { startPage, startLine, startNote, endPage, endLine, endNote } = selection.value;

  // 检查当前音符是否在选择范围内
  if (pageIndex < startPage || pageIndex > endPage) return false;
  if (pageIndex === startPage && lineIndex < startLine) return false;
  if (pageIndex === endPage && lineIndex > endLine) return false;
  if (pageIndex === startPage && lineIndex === startLine && noteIndex < startNote) return false;
  if (pageIndex === endPage && lineIndex === endLine && noteIndex > endNote) return false;

  return true;
};

// 判断光标是否在音符位置
const isCursorAtNote = (pageIndex: number, lineIndex: number, noteIndex: number) => {
  return (
    cursorPosition.value.page === pageIndex &&
    cursorPosition.value.line === lineIndex &&
    cursorPosition.value.noteIndex === noteIndex
  );
};

// 获取光标样式
const getCursorStyle = (pageIndex: number, lineIndex: number) => {
  if (cursorPosition.value.page !== pageIndex || cursorPosition.value.line !== lineIndex) {
    return { display: 'none' };
  }

  // 根据音符位置计算光标位置
  const noteArea = getNoteAreaElement(pageIndex, lineIndex);
  if (!noteArea) return { display: 'none' };

  if (cursorPosition.value.noteIndex === -1) {
    // 在行首
    return {
      left: '0px',
      height: '1.8em',
      top: '5px',
      position: 'absolute',
      width: '2px',
      backgroundColor: '#000',
      animation: 'cursorBlink 1s infinite',
    };
  } else {
    // 找到对应的音符元素
    const noteElements = noteArea.querySelectorAll('.music-symbol');
    if (cursorPosition.value.noteIndex < noteElements.length) {
      const noteElement = noteElements[cursorPosition.value.noteIndex] as HTMLElement;
      if (noteElement) {
        // 计算光标位置在音符后面
        return {
          left: `${noteElement.offsetLeft + noteElement.offsetWidth}px`,
          height: '1.8em',
          top: '5px',
          position: 'absolute',
          width: '2px',
          backgroundColor: '#000',
          animation: 'cursorBlink 1s infinite',
        };
      }
    }

    // 如果找不到对应音符，放在最后
    return {
      right: '0px',
      height: '1.8em',
      top: '5px',
      position: 'absolute',
      width: '2px',
      backgroundColor: '#000',
      animation: 'cursorBlink 1s infinite',
    };
  }
};

// 启动光标闪烁
const startCursorBlink = () => {
  if (cursorBlinkInterval.value) {
    clearInterval(cursorBlinkInterval.value);
  }

  cursorBlinkInterval.value = window.setInterval(() => {
    showCursor.value = !showCursor.value;
  }, 500);
};

// 重置光标闪烁
const resetCursorBlink = () => {
  showCursor.value = true;
  startCursorBlink();
};

// 将HTML内容转换为音符数组
const htmlToNotes = (htmlContent: string): MusicNote[] => {
  const notes: MusicNote[] = [];

  // 创建一个临时div来解析HTML
  const tempDiv = document.createElement('div');
  tempDiv.innerHTML = htmlContent;

  // 查找所有音符元素
  const symbols = tempDiv.querySelectorAll('.music-symbol');
  symbols.forEach((symbol) => {
    const name = symbol.getAttribute('data-note-type') || '';
    const value = symbol.textContent || '';

    notes.push({
      name,
      value,
      type: symbol.getAttribute('data-note-type') || undefined,
      html: symbol.outerHTML, // 添加HTML内容
    });
  });

  return notes;
};

// 将当前数据模型转换为新格式
const convertDataModel = () => {
  // 创建新的数据结构
  const newPages: Page[] = [];

  // 转换每一页
  pages.value.forEach((page: any) => {
    const newPage: Page = {
      lines: [],
    };

    // 转换每一行
    page.lines.forEach((line: any) => {
      // 使用类型断言访问旧的content属性
      // 注：这里假设原来的数据格式中行有content属性
      const oldContent = (line as any).content || '';

      const newLine: MusicLine = {
        notes: oldContent ? htmlToNotes(oldContent) : [],
        lyric: line.lyric,
      };

      newPage.lines.push(newLine);
    });

    newPages.push(newPage);
  });

  // 更新数据模型
  pages.value = newPages;
};

// 监听页面变化，确保DOM更新后有效的光标
watch(
  pages,
  () => {
    nextTick(() => {
      // 确保当前行有效
      const { page, line } = currentLine.value;
      if (pages.value[page] && pages.value[page].lines[line]) {
        const noteArea = getNoteAreaElement(page, line);
        if (noteArea) {
          activeNoteArea.value = noteArea;
          noteArea.focus();
        }
      } else if (pages.value.length > 0) {
        // 如果当前行无效，设置为第一行
        const lastPage = pages.value.length - 1;
        const lastLine = pages.value[lastPage].lines.length - 1;
        currentLine.value = {
          page: lastPage >= 0 ? lastPage : 0,
          line: lastLine >= 0 ? lastLine : 0,
        };

        nextTick(() => {
          const noteArea = getNoteAreaElement(currentLine.value.page, currentLine.value.line);
          if (noteArea) {
            activeNoteArea.value = noteArea;
            noteArea.focus();
            // 将光标移到末尾
            cursorPosition.value = {
              page: currentLine.value.page,
              line: currentLine.value.line,
              noteIndex: pages.value[currentLine.value.page].lines[currentLine.value.line].notes.length - 1,
              visible: true,
            };
          }
        });
      }
    });
  },
  { deep: true }
);

// 检查当前页面是否为空
const isCurrentPageEmpty = (): boolean => {
  const { page } = cursorPosition.value;

  // 检查页面是否存在
  if (page < 0 || page >= pages.value.length) return false;

  // 检查页面是否只有一行，且该行为空
  return pages.value[page].lines.length === 1 && pages.value[page].lines[0].notes.length === 0;
};

// 获取特定行的音符区域元素
const getNoteAreaElement = (pageIndex: number, lineIndex: number): HTMLElement | null => {
  const selector = `.note-area[data-page="${pageIndex}"][data-line="${lineIndex}"]`;
  return document.querySelector(selector) as HTMLElement | null;
};

// 确保指定的页面和行存在
const ensurePageAndLineExist = (pageIndex: number, lineIndex: number) => {
  // 确保页面存在
  while (pages.value.length <= pageIndex) {
    pages.value.push({
      lines: [
        {
          notes: [],
          lyric: '', // 初始化lyric为空字符串
          lyricEditing: false,
        },
      ],
    });
  }

  // 确保行存在
  while (pages.value[pageIndex].lines.length <= lineIndex) {
    pages.value[pageIndex].lines.push({
      notes: [],
      lyric: '', // 初始化lyric为空字符串
      lyricEditing: false,
    });
  }
};

// 处理滚轮缩放
const handleWheel = (e: WheelEvent) => {
  // 如果按住Ctrl键，则缩放而不是滚动
  if (e.ctrlKey || e.metaKey) {
    e.preventDefault();

    // 缩放步长
    const delta = e.deltaY > 0 ? -5 : 5;

    // 限制缩放范围
    zoom.value = Math.max(50, Math.min(150, zoom.value + delta));
  }
};

// 添加新页面
const addNewPage = () => {
  // 添加新页
  pages.value.push({
    lines: [
      {
        notes: [],
        lyric: '', // 改为空字符串而不是undefined
        lyricEditing: false,
      },
    ],
  });

  // 保存历史记录
  saveHistory();
};

// 删除当前页面（如果为空）
const removeCurrentPageIfEmpty = () => {
  const { page } = currentLine.value;

  // 不能删除第一页
  if (page === 0) return;

  // 检查页面是否为空
  if (isCurrentPageEmpty()) {
    // 删除当前页
    pages.value.splice(page, 1);

    // 移动到前一页
    currentLine.value = {
      page: page - 1,
      line: pages.value[page - 1].lines.length - 1,
    };

    // 保存历史记录
    saveHistory();
  }
};

// 添加歌词行
const addLyricLine = () => {
  const { page, line } = currentLine.value;

  console.log('添加歌词到行:', page, line, '当前lyric值:', pages.value[page].lines[line].lyric);

  // 确保当前行存在
  ensurePageAndLineExist(page, line);

  // 切换歌词显示状态（如果已有歌词则显示编辑界面，如果没有则创建）
  if (pages.value[page].lines[line].lyric !== undefined) {
    // 已有歌词，切换到编辑模式
    pages.value[page].lines[line].lyricEditing = !pages.value[page].lines[line].lyricEditing;
    console.log('切换编辑模式为:', pages.value[page].lines[line].lyricEditing);
  } else {
    // 添加歌词字段
    pages.value[page].lines[line].lyric = '';
    // 进入编辑模式
    pages.value[page].lines[line].lyricEditing = true;
    console.log('新建歌词并进入编辑模式');
  }

  // 保存历史记录
  saveHistory();

  // 在下一个渲染周期聚焦到歌词输入框
    nextTick(() => {
    if (pages.value[page].lines[line].lyricEditing) {
      const lyricInput = getLyricInputElement(page, line);
      if (lyricInput) {
        lyricInput.focus();
        console.log('已聚焦到歌词输入框');
      } else {
        console.log('未找到歌词输入框');
      }
    }
  });
};

// 获取歌词输入框元素 - 修改为支持el-input
const getLyricInputElement = (pageIndex: number, lineIndex: number): HTMLElement | null => {
  // 先尝试获取el-input组件
  const elInputSelector = `.el-input[data-page="${pageIndex}"][data-line="${lineIndex}"] input`;
  const elInput = document.querySelector(elInputSelector) as HTMLElement;
  if (elInput) return elInput;

  // 兼容原来的selector方式
  const selector = `.lyric-input[data-page="${pageIndex}"][data-line="${lineIndex}"]`;
  return document.querySelector(selector) as HTMLElement | null;
};

// 处理歌词输入完成
const handleLyricInputBlur = (event: FocusEvent, pageIndex: number, lineIndex: number, lyricEditing: boolean) => {
  console.log('歌词输入框失去焦点', event.target);
  console.log(lyricEditing,'------sad');

  // 获取输入内容
  const lyricText = (event.target as HTMLInputElement).value;

  // 更新歌词内容
  pages.value[pageIndex].lines[lineIndex].lyric = lyricText;

  // 退出编辑模式
  pages.value[pageIndex].lines[lineIndex].lyricEditing = false;

  // 保存历史记录
  saveHistory();

  // 检查当前活动元素是否是音符区域，如果不是，则需要聚焦回去
  const noteArea = getNoteAreaElement(pageIndex, lineIndex);
  if (noteArea && document.activeElement !== noteArea) {
    // 延迟一点以确保DOM更新完成
    setTimeout(() => {
      noteArea.focus();
      activeNoteArea.value = noteArea;
      console.log('已将焦点返回给音符区域');

      // 恢复光标可见性和闪烁
      cursorPosition.value.visible = true;
      resetCursorBlink();
    }, 50);
  }
};

// 处理歌词输入回车事件
const handleLyricInputKeydown = (event: KeyboardEvent, pageIndex: number, lineIndex: number) => {
  // 阻止事件冒泡，防止触发音符区域的键盘事件
  event.stopPropagation();

  // 按下回车键时，保存歌词内容
  if (event.key === 'Enter') {
    // 阻止默认行为
    event.preventDefault();

    // 获取输入内容
    const lyricText = (event.target as HTMLInputElement).value;
    console.log('保存歌词:', lyricText);

    // 更新歌词内容
    pages.value[pageIndex].lines[lineIndex].lyric = lyricText;

    // 退出编辑模式
    pages.value[pageIndex].lines[lineIndex].lyricEditing = false;

    // 保存历史记录
    saveHistory();

    // 聚焦回音符区域 - 延迟一点以确保DOM更新完成
    setTimeout(() => {
      const noteArea = getNoteAreaElement(pageIndex, lineIndex);
      if (noteArea) {
        noteArea.focus();
        activeNoteArea.value = noteArea;
        console.log('已将焦点返回给音符区域');

        // 恢复光标可见性和闪烁
        cursorPosition.value.visible = true;
        resetCursorBlink();
      }
    }, 50);
  }
  // 处理Escape键，取消编辑
  else if (event.key === 'Escape') {
    // 阻止默认行为
    event.preventDefault();
    console.log('取消编辑歌词');

    // 退出编辑模式，不保存更改
    pages.value[pageIndex].lines[lineIndex].lyricEditing = false;

    // 聚焦回音符区域 - 延迟一点以确保DOM更新完成
    setTimeout(() => {
    const noteArea = getNoteAreaElement(pageIndex, lineIndex);
    if (noteArea) {
      noteArea.focus();
      activeNoteArea.value = noteArea;
        console.log('已将焦点返回给音符区域');

        // 恢复光标可见性和闪烁
        cursorPosition.value.visible = true;
        resetCursorBlink();
      }
    }, 50);
  }
  // 处理删除键，如果输入框为空，则删除整个歌词行
  else if ((event.key === 'Backspace' || event.key === 'Delete') && (event.target as HTMLInputElement).value === '') {
    // 阻止默认行为
    event.preventDefault();
    console.log('删除空的歌词行');

    // 删除歌词行
    removeLyric(pageIndex, lineIndex);

    // 聚焦回音符区域 - 延迟一点以确保DOM更新完成
    setTimeout(() => {
      const noteArea = getNoteAreaElement(pageIndex, lineIndex);
      if (noteArea) {
        noteArea.focus();
        activeNoteArea.value = noteArea;
        console.log('已将焦点返回给音符区域');

        // 恢复光标可见性和闪烁
        cursorPosition.value.visible = true;
        resetCursorBlink();
      }
    }, 50);
  }
};

// 删除歌词行
const removeLyric = (pageIndex: number, lineIndex: number, event?: MouseEvent) => {
  console.log('删除歌词行:', pageIndex, lineIndex);

  // 阻止事件冒泡，防止触发音符区域的点击事件
  if (event) {
    event.stopPropagation();
    event.preventDefault();
  }

  // 确保页面和行存在
  if (
    pageIndex < 0 ||
    pageIndex >= pages.value.length ||
    lineIndex < 0 ||
    lineIndex >= pages.value[pageIndex].lines.length
  ) {
    console.warn('无效的页面或行索引');
    return;
  }

  // 删除歌词字段
  delete pages.value[pageIndex].lines[lineIndex].lyric;
  // 退出编辑模式
  pages.value[pageIndex].lines[lineIndex].lyricEditing = false;

  // 保存历史记录
  saveHistory();

  console.log('歌词行已删除');
};

// 历史记录管理
const saveHistory = () => {
  // 如果禁止保存，则直接返回
  if (preventHistorySave.value) return;

  // 序列化整个编辑器状态
  const editorState = JSON.stringify(pages.value);

  // 避免重复保存相同状态
  if (state.history.length > 0 && state.historyIndex >= 0 && state.history[state.historyIndex] === editorState) {
    console.log('状态未变，不保存历史');
    return;
  }

  state.history = state.history.slice(0, state.historyIndex + 1);
  state.history.push(editorState);
  state.historyIndex = state.history.length - 1;

  console.log('保存历史记录 #', state.historyIndex);
};

// 处理复制操作
const handleCopy = () => {
  console.log('开始复制操作, 选择状态:', selection.value.active);

  // 如果没有选中内容，不进行任何操作
  if (!selection.value.active) {
    console.log('没有选中内容，无法复制');
    return;
  }

  const { startPage, startLine, startNote, endPage, endLine, endNote } = selection.value;
  console.log('复制范围:', startPage, startLine, startNote, '到', endPage, endLine, endNote);

  // 收集选中的音符
  const copiedNotes = [];

  try {
    // 如果选择范围在同一行
    if (startPage === endPage && startLine === endLine) {
      // 将该行中的选中音符添加到复制列表
      for (let i = startNote; i <= endNote; i++) {
        if (i < pages.value[startPage].lines[startLine].notes.length) {
          copiedNotes.push(JSON.parse(JSON.stringify(pages.value[startPage].lines[startLine].notes[i])));
        }
      }
    } else {
      // 处理跨行或跨页的选择

      // 第一行: 添加开始位置之后的所有音符
      const firstLineNotes = pages.value[startPage].lines[startLine].notes;
      for (let i = startNote; i < firstLineNotes.length; i++) {
        copiedNotes.push(JSON.parse(JSON.stringify(firstLineNotes[i])));
      }

      // 中间所有行: 添加全部音符
      // 同一页内的中间行
      if (startPage === endPage) {
        for (let i = startLine + 1; i < endLine; i++) {
          const lineNotes = pages.value[startPage].lines[i].notes;
          for (let j = 0; j < lineNotes.length; j++) {
            copiedNotes.push(JSON.parse(JSON.stringify(lineNotes[j])));
          }
        }
      } else {
        // 跨页的中间行

        // 起始页中间行
        for (let i = startLine + 1; i < pages.value[startPage].lines.length; i++) {
          const lineNotes = pages.value[startPage].lines[i].notes;
          for (let j = 0; j < lineNotes.length; j++) {
            copiedNotes.push(JSON.parse(JSON.stringify(lineNotes[j])));
          }
        }

        // 中间页的所有行
        for (let p = startPage + 1; p < endPage; p++) {
          for (let i = 0; i < pages.value[p].lines.length; i++) {
            const lineNotes = pages.value[p].lines[i].notes;
            for (let j = 0; j < lineNotes.length; j++) {
              copiedNotes.push(JSON.parse(JSON.stringify(lineNotes[j])));
            }
          }
        }

        // 结束页前面的行
        for (let i = 0; i < endLine; i++) {
          const lineNotes = pages.value[endPage].lines[i].notes;
          for (let j = 0; j < lineNotes.length; j++) {
            copiedNotes.push(JSON.parse(JSON.stringify(lineNotes[j])));
          }
        }
      }

      // 最后一行: 添加结束位置之前的所有音符
      if (endPage < pages.value.length && endLine < pages.value[endPage].lines.length) {
        const lastLineNotes = pages.value[endPage].lines[endLine].notes;
        for (let i = 0; i <= endNote && i < lastLineNotes.length; i++) {
          copiedNotes.push(JSON.parse(JSON.stringify(lastLineNotes[i])));
        }
      }
    }

    console.log('已收集到的音符数量:', copiedNotes.length);

    // 存储到本地剪贴板变量中
    clipboardData.value = copiedNotes;

    // 创建一个特殊标记，表明这是音符数据
    const musicNoteData = {
      type: 'XMusicScore-notes',
      version: '1.0',
      data: copiedNotes,
    };

    // 尝试存储到系统剪贴板
    try {
      // 将音符转换为可保存的格式
      const clipboardText = JSON.stringify(musicNoteData);
      console.log('准备复制到系统剪贴板，数据长度:', clipboardText.length);

      // 保存到剪贴板
      if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard
          .writeText(clipboardText)
          .then(() => {
            console.log('已复制音符到系统剪贴板');
          })
          .catch((error: any) => {
            console.error('无法复制到系统剪贴板, 但已保存在内部剪贴板中:', error.message);
          });
      } else {
        // 创建临时文本区域
        const textArea = document.createElement('textarea');
        textArea.value = clipboardText;
        document.body.appendChild(textArea);
        textArea.select();

        // 尝试使用document.execCommand复制
        const successful = document.execCommand('copy');
        if (successful) {
          console.log('使用传统方法成功复制到剪贴板');
        } else {
          console.warn('传统方法复制失败，但已保存到内部剪贴板');
        }

        // 移除临时元素
        document.body.removeChild(textArea);
      }
    } catch (error: any) {
      console.error('复制到系统剪贴板失败, 但已保存在内部剪贴板中:', error.message);
    }
  } catch (error: any) {
    console.error('复制操作出错:', error.message);
  }
};

// 处理粘贴操作
const handlePaste = async () => {
  console.log('开始粘贴操作');

  try {
    let notesToPaste = [];
    let pasteSuccess = false;

    // 首先尝试从系统剪贴板获取数据
    try {
      if (navigator.clipboard && navigator.clipboard.readText) {
        const clipboardText = await navigator.clipboard.readText();
        console.log('从系统剪贴板读取的文本长度:', clipboardText ? clipboardText.length : 0);

        // 尝试解析剪贴板数据
        if (clipboardText && clipboardText.trim()) {
          try {
            const parsedData = JSON.parse(clipboardText);
            console.log('解析的数据类型:', parsedData ? typeof parsedData : 'null');

            // 首先检查是否是我们的特殊格式
            if (parsedData && parsedData.type === 'XMusicScore-notes' && Array.isArray(parsedData.data)) {
              notesToPaste = parsedData.data;
              pasteSuccess = true;
              console.log('从特殊格式中获取音符数量:', notesToPaste.length);
            }
            // 验证解析出的数据是否为音符数组
            else if (
              Array.isArray(parsedData) &&
              parsedData.length > 0 &&
              parsedData.every((note) => note && typeof note === 'object' && 'value' in note)
            ) {
              notesToPaste = parsedData;
              pasteSuccess = true;
              console.log('从系统剪贴板获取到的音符数量:', notesToPaste.length);
      } else {
              console.warn('系统剪贴板中的数据不是有效的音符格式:', typeof parsedData);
            }
          } catch (error: any) {
            console.warn('解析系统剪贴板数据失败，不是有效的JSON:', error.message);
            // 剪贴板内容不是JSON，可能是普通文本
            // 这里我们可以选择不处理或者创建简单的音符
    }
  } else {
          console.warn('系统剪贴板为空');
        }
      } else {
        console.warn('浏览器不支持Clipboard API');
      }
    } catch (error: any) {
      console.warn('读取系统剪贴板失败:', error.message);
    }

    // 如果系统剪贴板粘贴失败，则使用内部剪贴板
    if (!pasteSuccess && clipboardData.value && clipboardData.value.length > 0) {
      notesToPaste = JSON.parse(JSON.stringify(clipboardData.value));
      pasteSuccess = true;
      console.log('使用内部剪贴板中的音符数量:', notesToPaste.length);
    }

    // 如果没有可粘贴的内容，直接返回
    if (!pasteSuccess || notesToPaste.length === 0) {
      console.warn('没有可粘贴的内容');
      return;
    }

    // 如果有选中内容，先删除选中内容
    if (selection.value.active) {
      deleteSelectedNotes();
    }

    // 获取当前光标位置
    const { page, line, noteIndex } = cursorPosition.value;

    // 确保页面和行存在
    ensurePageAndLineExist(page, line);

    const currentLineNotes = pages.value[page].lines[line].notes;

    // 确定插入位置
    let insertIndex = noteIndex + 1;
    if (noteIndex === -1) {
      insertIndex = 0;
    }

    console.log('准备插入音符, 位置:', page, line, insertIndex);

    // 插入音符
    for (let i = 0; i < notesToPaste.length; i++) {
      const noteToInsert = JSON.parse(JSON.stringify(notesToPaste[i]));
      // 确保音符有必要的字段
      if (!noteToInsert.html && noteToInsert.value) {
        noteToInsert.html = `<span class="music-symbol" data-note-type="${noteToInsert.name || ''}">${
          noteToInsert.value
        }</span>`;
      }
      currentLineNotes.splice(insertIndex + i, 0, noteToInsert);
    }

    // 更新光标位置到粘贴内容的末尾
    cursorPosition.value = {
      page,
      line,
      noteIndex: insertIndex + notesToPaste.length - 1,
      visible: true,
    };

    // 清除选择状态
    selection.value.active = false;

    // 重置光标闪烁
    resetCursorBlink();

    // 保存历史记录
  saveHistory();

    console.log('粘贴完成，共插入音符:', notesToPaste.length);
  } catch (error: any) {
    console.error('粘贴操作发生错误:', error);
  }
};

// 删除选中的音符
const deleteSelectedNotes = () => {
  console.log('开始删除选中音符');

  if (!selection.value.active) {
    console.log('没有选中内容，无法删除');
    return;
  }

  const { startPage, startLine, startNote, endPage, endLine, endNote } = selection.value;
  console.log('删除范围:', startPage, startLine, startNote, '到', endPage, endLine, endNote);

  // 如果选择范围在同一行
  if (startPage === endPage && startLine === endLine) {
    // 检查起始和结束索引是否有效
    if (startNote <= endNote && startNote >= 0 && endNote < pages.value[startPage].lines[startLine].notes.length) {
      // 删除该行中的选中音符
      const notesToDelete = endNote - startNote + 1;
      console.log('在同一行中删除音符数量:', notesToDelete);
      pages.value[startPage].lines[startLine].notes.splice(startNote, notesToDelete);

      // 更新光标位置
      cursorPosition.value = {
        page: startPage,
        line: startLine,
        noteIndex: startNote - 1 >= -1 ? startNote - 1 : -1,
        visible: true,
      };
    } else {
      console.warn('选择范围无效');
    }
  } else {
    // 处理跨行或跨页的选择 - 这需要更复杂的逻辑

    // 第一行: 保留开始位置之前的所有音符
    const firstLineNotes = pages.value[startPage].lines[startLine].notes.slice(0, startNote);

    // 最后一行: 保留结束位置之后的所有音符
    const lastLineNotes = pages.value[endPage].lines[endLine].notes.slice(endNote + 1);

    // 合并第一行与最后一行
    const mergedNotes = [...firstLineNotes, ...lastLineNotes];
    console.log('合并后的音符数量:', mergedNotes.length);

    // 更新第一行的音符
    pages.value[startPage].lines[startLine].notes = mergedNotes;

    // 如果是在同一页内
    if (startPage === endPage) {
      // 删除中间的所有行
      console.log('删除同一页内的行数:', endLine - startLine);
      pages.value[startPage].lines.splice(startLine + 1, endLine - startLine);
    } else {
      // 跨页删除处理

      // 删除第一页中startLine之后的所有行
      pages.value[startPage].lines.splice(startLine + 1);

      // 删除中间所有页
      if (endPage - startPage > 1) {
        pages.value.splice(startPage + 1, endPage - startPage - 1);
      }

      // 删除最后一页中endLine之前的所有行
      const adjustedEndPage = startPage + 1; // 因为中间页已被删除
      if (adjustedEndPage < pages.value.length && endLine < pages.value[adjustedEndPage].lines.length) {
        pages.value[adjustedEndPage].lines.splice(0, endLine);

        // 如果最后一页没有行了，删除该页
        if (pages.value[adjustedEndPage].lines.length === 0) {
          pages.value.splice(adjustedEndPage, 1);
        }
      }
    }

    // 更新光标位置到合并后的位置
    cursorPosition.value = {
      page: startPage,
      line: startLine,
      noteIndex: firstLineNotes.length - 1 >= -1 ? firstLineNotes.length - 1 : -1,
      visible: true,
    };
  }

  // 重置选择状态
  selection.value.active = false;

  // 聚焦到音符区域
  const noteArea = getNoteAreaElement(cursorPosition.value.page, cursorPosition.value.line);
  if (noteArea) {
    noteArea.focus();
    activeNoteArea.value = noteArea;
  }

  // 保存历史记录
  saveHistory();

  console.log('删除选中音符完成');
};

// 组件初始化
onMounted(() => {
  // 转换现有数据模型
  convertDataModel();

  // 初始化
  saveHistory();

  // 启动光标闪烁
  startCursorBlink();

  // 计算顶部偏移量并设置CSS变量
  calculateTopOffset();

  // 添加事件监听器
  window.addEventListener('resize', calculateTopOffset);
  window.addEventListener('beforeunload', cleanupTimers);

  // 确保默认页面有焦点
      nextTick(() => {
    const firstNoteArea = getNoteAreaElement(0, 0);
    if (firstNoteArea) {
      firstNoteArea.focus();
      activeNoteArea.value = firstNoteArea;

      // 设置初始光标位置
      cursorPosition.value = {
        page: 0,
        line: 0,
        noteIndex: -1,
        visible: true,
      };
    }
  });
});

onUnmounted(() => {
  // 清理计时器
  if (cursorBlinkInterval.value) {
    clearInterval(cursorBlinkInterval.value);
  }

  // 移除事件监听器
  window.removeEventListener('resize', calculateTopOffset);
  window.removeEventListener('beforeunload', cleanupTimers);
});

// 在组件中添加计算顶部偏移量的函数
const calculateTopOffset = () => {
  // 尝试多种选择器来确保能够找到元素

  // 1. 寻找el-menu元素高度
  let menuHeight = 0;
  // 尝试不同的选择器
  const menuSelectors = ['.el-menu', 'el-menu', '.left_menu'];
  for (const selector of menuSelectors) {
    const element = document.querySelector(selector);
    if (element) {
      menuHeight = element.getBoundingClientRect().height;
      console.log(`找到菜单元素(${selector}):`, menuHeight);
      break;
    }
  }

  // 2. 寻找el-tabs元素高度
  let tabsHeight = 0;
  // 尝试不同的选择器
  const tabsSelectors = ['.el-tabs__header', '.demo-tabs .el-tabs__header', '.el-tabs'];
  for (const selector of tabsSelectors) {
    const element = document.querySelector(selector);
    if (element) {
      tabsHeight = element.getBoundingClientRect().height;
      console.log(`找到标签页元素(${selector}):`, tabsHeight);
      break;
    }
  }

  // 如果没有找到元素，手动设置一个默认值
  if (menuHeight === 0) {
    console.log('未找到菜单元素，使用默认值');
    menuHeight = 40; // 默认菜单高度
  }

  if (tabsHeight === 0) {
    console.log('未找到标签页元素，使用默认值');
    tabsHeight = 40; // 默认标签页高度
  }

  // 3. 考虑其他可能的固定顶部元素和边距
  let additionalOffset = 0;
  const editorContainer = document.querySelector('.editor-container');
  if (editorContainer) {
    const rect = editorContainer.getBoundingClientRect();
    const expectedTop = menuHeight + tabsHeight;
    // 如果容器顶部位置大于menu和tabs的高度总和，可能有其他元素或边距
    if (rect.top > expectedTop) {
      additionalOffset = rect.top - expectedTop;
      console.log('发现额外偏移:', additionalOffset);
    }
  }

  // 计算总偏移量
  const topOffset = menuHeight + tabsHeight + additionalOffset;

  // 设置CSS变量
  document.documentElement.style.setProperty('--top-offset', `${topOffset}px`);
  console.log('最终设置顶部偏移量:', { menuHeight, tabsHeight, additionalOffset, total: topOffset }, 'px');

  // 为了确保我们计算出的高度是正确的，手动验证一下DOM结构
  console.log('DOM结构检查:');
  console.log(
    '- Body直接子元素:',
    Array.from(document.body.children).map(
      (el) => `${el.tagName.toLowerCase()}${el.className ? '.' + el.className.replace(/\s+/g, '.') : ''}`
    )
  );
  const allMenus = document.querySelectorAll('[class*="menu"], [class*="Menu"]');
  console.log(
    '- 所有菜单相关元素:',
    Array.from(allMenus).map(
      (el) => `${el.tagName.toLowerCase()}${el.className ? '.' + el.className.replace(/\s+/g, '.') : ''}`
    )
  );
  const allTabs = document.querySelectorAll('[class*="tab"], [class*="Tab"]');
  console.log(
    '- 所有标签页相关元素:',
    Array.from(allTabs).map(
      (el) => `${el.tagName.toLowerCase()}${el.className ? '.' + el.className.replace(/\s+/g, '.') : ''}`
    )
  );
};

// 处理音符区域获得焦点
const handleNoteFocus = (event: FocusEvent, pageIndex: number, lineIndex: number) => {
  // 更新当前行
  currentLine.value = { page: pageIndex, line: lineIndex };

  // 记录激活的音符区域
  activeNoteArea.value = event.target as HTMLElement;

  // 重置光标闪烁
  resetCursorBlink();

  console.log('音符区域获得焦点:', pageIndex, lineIndex);
};

// 处理音符区域失去焦点
const handleNoteBlur = () => {
  // 可能需要处理失去焦点的逻辑，如保存状态等
  console.log('音符区域失去焦点');
};

// 处理音符区域点击
const handleNoteClick = (event: MouseEvent, pageIndex: number, lineIndex: number) => {
  // 阻止可能的默认行为
  event.preventDefault();

  // 记录当前行
  currentLine.value = { page: pageIndex, line: lineIndex };

  // 获取点击的位置
  const clickX = event.clientX;

  // 获取音符区域
  const noteArea = event.currentTarget as HTMLElement;
  activeNoteArea.value = noteArea;

  // 计算点击位置在哪个音符附近
  const noteElements = noteArea.querySelectorAll('.note-span');
  let closestNoteIndex = -1;
  let minDistance = Infinity;

  noteElements.forEach((noteElement, index) => {
    const rect = (noteElement as HTMLElement).getBoundingClientRect();
    const noteCenter = rect.left + rect.width / 2;
    const distance = Math.abs(clickX - noteCenter);

    // 如果是最近的音符，记录索引
    if (distance < minDistance) {
      minDistance = distance;
      closestNoteIndex = index;
    }
  });

  // 更新光标位置
  cursorPosition.value = {
    page: pageIndex,
    line: lineIndex,
    noteIndex: closestNoteIndex,
    visible: true,
  };

  // 如果是双击，可以选择整个音符
  if (event.detail === 2 && closestNoteIndex !== -1) {
    // 设置选择范围为当前音符
    selection.value = {
      active: true,
      startPage: pageIndex,
      startLine: lineIndex,
      startNote: closestNoteIndex,
      endPage: pageIndex,
      endLine: lineIndex,
      endNote: closestNoteIndex,
    };
  } else {
    // 单击，清除选择
    selection.value.active = false;
  }

  // 重置光标闪烁
  resetCursorBlink();

  console.log('点击音符区域:', pageIndex, lineIndex, '最近的音符索引:', closestNoteIndex);
};

// 处理键盘事件
const handleKeyDown = (event: KeyboardEvent, pageIndex: number, lineIndex: number) => {
  // 阻止可能的默认行为
  // event.preventDefault();

  // 获取当前光标位置
  const { noteIndex } = cursorPosition.value;
  const currentNotes = pages.value[pageIndex].lines[lineIndex].notes;

  console.log('键盘事件:', event.key, '当前页面:', pageIndex, '当前行:', lineIndex, '当前音符索引:', noteIndex);

  // 处理不同的键盘事件
  switch (event.key) {
    case 'ArrowLeft':
      // 向左移动光标
      event.preventDefault();
      if (noteIndex > -1) {
        // 当前在音符中间，向左移动一个
        cursorPosition.value.noteIndex = noteIndex - 1;
      } else if (noteIndex === -1) {
        // 当前在行首，需要移动到上一行末尾
        if (lineIndex > 0) {
          // 同一页上一行
          const prevLineIndex = lineIndex - 1;
          const prevLineNotes = pages.value[pageIndex].lines[prevLineIndex].notes;

          cursorPosition.value = {
            page: pageIndex,
            line: prevLineIndex,
            noteIndex: prevLineNotes.length - 1,
            visible: true,
          };

          // 更新当前行
          currentLine.value = { page: pageIndex, line: prevLineIndex };

          // 聚焦到上一行
          const noteArea = getNoteAreaElement(pageIndex, prevLineIndex);
          if (noteArea) {
            noteArea.focus();
            activeNoteArea.value = noteArea;
          }
        } else if (pageIndex > 0) {
          // 需要移动到上一页的最后一行
          const prevPageIndex = pageIndex - 1;
          const prevPage = pages.value[prevPageIndex];
          const prevLineIndex = prevPage.lines.length - 1;
          const prevLineNotes = prevPage.lines[prevLineIndex].notes;

          cursorPosition.value = {
            page: prevPageIndex,
            line: prevLineIndex,
            noteIndex: prevLineNotes.length - 1,
            visible: true,
          };

          // 更新当前行
          currentLine.value = { page: prevPageIndex, line: prevLineIndex };

          // 聚焦到上一页的最后一行
          const noteArea = getNoteAreaElement(prevPageIndex, prevLineIndex);
          if (noteArea) {
            noteArea.focus();
            activeNoteArea.value = noteArea;
          }
        }
      }
      break;

    case 'ArrowRight':
      // 向右移动光标
      event.preventDefault();
      if (noteIndex < currentNotes.length - 1) {
        // 当前不在行尾，向右移动一个
        cursorPosition.value.noteIndex = noteIndex + 1;
      } else {
        // 当前在行尾，需要移动到下一行开始
        if (lineIndex < pages.value[pageIndex].lines.length - 1) {
          // 同一页下一行
          const nextLineIndex = lineIndex + 1;

          cursorPosition.value = {
            page: pageIndex,
            line: nextLineIndex,
            noteIndex: -1,
            visible: true,
          };

          // 更新当前行
          currentLine.value = { page: pageIndex, line: nextLineIndex };

          // 聚焦到下一行
          const noteArea = getNoteAreaElement(pageIndex, nextLineIndex);
          if (noteArea) {
            noteArea.focus();
            activeNoteArea.value = noteArea;
          }
        } else if (pageIndex < pages.value.length - 1) {
          // 需要移动到下一页的第一行
          const nextPageIndex = pageIndex + 1;

          cursorPosition.value = {
            page: nextPageIndex,
            line: 0,
            noteIndex: -1,
            visible: true,
          };

          // 更新当前行
          currentLine.value = { page: nextPageIndex, line: 0 };

          // 聚焦到下一页的第一行
          const noteArea = getNoteAreaElement(nextPageIndex, 0);
          if (noteArea) {
            noteArea.focus();
            activeNoteArea.value = noteArea;
          }
        }
      }
      break;

    case 'ArrowUp':
      // 向上移动光标到上一行
      event.preventDefault();
      if (lineIndex > 0) {
        // 同一页上一行
        const prevLineIndex = lineIndex - 1;
        const prevLineNotes = pages.value[pageIndex].lines[prevLineIndex].notes;

        // 保持水平相对位置
        let targetNoteIndex = Math.min(noteIndex, prevLineNotes.length - 1);

        cursorPosition.value = {
          page: pageIndex,
          line: prevLineIndex,
          noteIndex: targetNoteIndex,
          visible: true,
        };

        // 更新当前行
        currentLine.value = { page: pageIndex, line: prevLineIndex };

        // 聚焦到上一行
        const noteArea = getNoteAreaElement(pageIndex, prevLineIndex);
        if (noteArea) {
          noteArea.focus();
          activeNoteArea.value = noteArea;
        }
      } else if (pageIndex > 0) {
        // 需要移动到上一页的最后一行
        const prevPageIndex = pageIndex - 1;
        const prevPage = pages.value[prevPageIndex];
        const prevLineIndex = prevPage.lines.length - 1;
        const prevLineNotes = prevPage.lines[prevLineIndex].notes;

        // 保持水平相对位置
        let targetNoteIndex = Math.min(noteIndex, prevLineNotes.length - 1);

        cursorPosition.value = {
          page: prevPageIndex,
          line: prevLineIndex,
          noteIndex: targetNoteIndex,
          visible: true,
        };

        // 更新当前行
        currentLine.value = { page: prevPageIndex, line: prevLineIndex };

        // 聚焦到上一页的最后一行
        const noteArea = getNoteAreaElement(prevPageIndex, prevLineIndex);
        if (noteArea) {
          noteArea.focus();
          activeNoteArea.value = noteArea;
        }
      }
      break;

    case 'ArrowDown':
      // 向下移动光标到下一行
      event.preventDefault();
      if (lineIndex < pages.value[pageIndex].lines.length - 1) {
        // 同一页下一行
        const nextLineIndex = lineIndex + 1;
        const nextLineNotes = pages.value[pageIndex].lines[nextLineIndex].notes;

        // 保持水平相对位置
        let targetNoteIndex = Math.min(noteIndex, nextLineNotes.length - 1);

        cursorPosition.value = {
          page: pageIndex,
          line: nextLineIndex,
          noteIndex: targetNoteIndex,
          visible: true,
        };

        // 更新当前行
        currentLine.value = { page: pageIndex, line: nextLineIndex };

        // 聚焦到下一行
        const noteArea = getNoteAreaElement(pageIndex, nextLineIndex);
        if (noteArea) {
          noteArea.focus();
          activeNoteArea.value = noteArea;
        }
      } else if (pageIndex < pages.value.length - 1) {
        // 需要移动到下一页的第一行
        const nextPageIndex = pageIndex + 1;
        const nextLineNotes = pages.value[nextPageIndex].lines[0].notes;

        // 保持水平相对位置
        let targetNoteIndex = Math.min(noteIndex, nextLineNotes.length - 1);

        cursorPosition.value = {
          page: nextPageIndex,
          line: 0,
          noteIndex: targetNoteIndex,
          visible: true,
        };

        // 更新当前行
        currentLine.value = { page: nextPageIndex, line: 0 };

        // 聚焦到下一页的第一行
        const noteArea = getNoteAreaElement(nextPageIndex, 0);
        if (noteArea) {
          noteArea.focus();
          activeNoteArea.value = noteArea;
        }
      }
      break;

    case 'Delete':
    case 'Backspace':
      // 删除音符
      event.preventDefault();

      // 如果有选中内容，删除选中内容
      if (selection.value.active) {
        deleteSelectedNotes();
        return;
      }
      
      // 否则，删除当前光标前/后的音符
      if (event.key === 'Backspace') {
        // 删除光标前的音符
        if (noteIndex > -1) {
          // 删除指定位置的音符
          pages.value[pageIndex].lines[lineIndex].notes.splice(noteIndex, 1);

          // 更新光标位置
          cursorPosition.value.noteIndex = noteIndex - 1;

          // 保存历史记录
          saveHistory();
        } else if (noteIndex === -1 && (lineIndex > 0 || pageIndex > 0)) {
          // 当前在行首，需要合并到上一行
          if (lineIndex > 0) {
            // 同一页中的上一行
            const prevLineIndex = lineIndex - 1;
            const prevLineNotes = pages.value[pageIndex].lines[prevLineIndex].notes;
            const currentLineNotes = pages.value[pageIndex].lines[lineIndex].notes;

            // 记录上一行末尾的索引
            const prevLineEndIndex = prevLineNotes.length - 1;

            // 合并当前行到上一行
            pages.value[pageIndex].lines[prevLineIndex].notes = [...prevLineNotes, ...currentLineNotes];

        // 删除当前行
            pages.value[pageIndex].lines.splice(lineIndex, 1);

            // 更新当前行和光标位置
            currentLine.value = { page: pageIndex, line: prevLineIndex };
            cursorPosition.value = {
              page: pageIndex,
              line: prevLineIndex,
              noteIndex: prevLineEndIndex,
              visible: true,
            };

            // 聚焦到上一行
            const noteArea = getNoteAreaElement(pageIndex, prevLineIndex);
            if (noteArea) {
              noteArea.focus();
              activeNoteArea.value = noteArea;
            }

            // 保存历史记录
            saveHistory();
          } else if (pageIndex > 0) {
            // 需要合并到上一页的最后一行
            const prevPageIndex = pageIndex - 1;
            const prevPage = pages.value[prevPageIndex];
            const prevLineIndex = prevPage.lines.length - 1;
            const prevLineNotes = prevPage.lines[prevLineIndex].notes;
            const currentLineNotes = pages.value[pageIndex].lines[0].notes;

            // 记录上一行末尾的索引
            const prevLineEndIndex = prevLineNotes.length - 1;

            // 合并当前行到上一页的最后一行
            pages.value[prevPageIndex].lines[prevLineIndex].notes = [...prevLineNotes, ...currentLineNotes];

            // 如果当前页只有这一行，删除整个页面，否则只删除第一行
            if (pages.value[pageIndex].lines.length === 1) {
              pages.value.splice(pageIndex, 1);
            } else {
              pages.value[pageIndex].lines.splice(0, 1);
            }

            // 更新当前行和光标位置
            currentLine.value = { page: prevPageIndex, line: prevLineIndex };
            cursorPosition.value = {
              page: prevPageIndex,
              line: prevLineIndex,
              noteIndex: prevLineEndIndex,
              visible: true,
            };

            // 聚焦到上一页的最后一行
            const noteArea = getNoteAreaElement(prevPageIndex, prevLineIndex);
            if (noteArea) {
              noteArea.focus();
              activeNoteArea.value = noteArea;
            }

            // 保存历史记录
            saveHistory();
          }
        }
      } else if (event.key === 'Delete') {
        // 删除光标后的音符
        if (noteIndex < currentNotes.length - 1) {
          // 删除下一个音符
          pages.value[pageIndex].lines[lineIndex].notes.splice(noteIndex + 1, 1);

          // 光标位置不变

          // 保存历史记录
          saveHistory();
        } else if (
          noteIndex === currentNotes.length - 1 &&
          (lineIndex < pages.value[pageIndex].lines.length - 1 || pageIndex < pages.value.length - 1)
        ) {
          // 当前在行尾，需要合并下一行
          if (lineIndex < pages.value[pageIndex].lines.length - 1) {
            // 同一页中的下一行
            const nextLineIndex = lineIndex + 1;
            const nextLineNotes = pages.value[pageIndex].lines[nextLineIndex].notes;

            // 合并下一行到当前行
            pages.value[pageIndex].lines[lineIndex].notes = [...currentNotes, ...nextLineNotes];

            // 删除下一行
            pages.value[pageIndex].lines.splice(nextLineIndex, 1);

            // 光标位置不变

            // 保存历史记录
            saveHistory();
          } else if (pageIndex < pages.value.length - 1) {
            // 需要合并下一页的第一行
            const nextPageIndex = pageIndex + 1;
            const nextLineNotes = pages.value[nextPageIndex].lines[0].notes;

            // 合并下一页的第一行到当前行
            pages.value[pageIndex].lines[lineIndex].notes = [...currentNotes, ...nextLineNotes];

            // 如果下一页只有这一行，删除整个页面，否则只删除第一行
            if (pages.value[nextPageIndex].lines.length === 1) {
              pages.value.splice(nextPageIndex, 1);
            } else {
              pages.value[nextPageIndex].lines.splice(0, 1);
            }

            // 光标位置不变

            // 保存历史记录
            saveHistory();
          }
        }
      }

      // 重置光标闪烁
      resetCursorBlink();
      break;

    case 'Enter':
      // 插入新行
      event.preventDefault();

      // 获取当前行的音符
      const currentLineNotes = pages.value[pageIndex].lines[lineIndex].notes;
      let notesAfterCursor: MusicNote[] = [];

      // 如果光标不在行首，分割当前行
      if (noteIndex >= 0) {
        // 提取光标后的音符
        notesAfterCursor = currentLineNotes.splice(noteIndex + 1);
      }

      // 创建新行
      const newLineIndex = lineIndex + 1;

      // 插入新行，确保包含 lyric 属性（初始化为空字符串）
      pages.value[pageIndex].lines.splice(newLineIndex, 0, {
        notes: notesAfterCursor,
        lyric: '', // 改为空字符串而不是undefined
        lyricEditing: false, // 确保 lyricEditing 属性初始化为 false
      });

      // 更新当前行和光标位置
      currentLine.value = { page: pageIndex, line: newLineIndex };
      cursorPosition.value = {
        page: pageIndex,
        line: newLineIndex,
        noteIndex: -1,
        visible: true,
      };

      // 聚焦到新行
        nextTick(() => {
        const noteArea = getNoteAreaElement(pageIndex, newLineIndex);
        if (noteArea) {
          noteArea.focus();
          activeNoteArea.value = noteArea;
        }
      });

      // 保存历史记录
        saveHistory();
      break;

    case 'a':
      // 全选 (Ctrl+A)
      if (event.ctrlKey || event.metaKey) {
        event.preventDefault();

        if (currentNotes.length > 0) {
          // 选择当前行的所有音符
          selection.value = {
            active: true,
            startPage: pageIndex,
            startLine: lineIndex,
            startNote: 0,
            endPage: pageIndex,
            endLine: lineIndex,
            endNote: currentNotes.length - 1,
          };
        }
      }
      break;

    case 'c':
      // 复制 (Ctrl+C)
      if (event.ctrlKey || event.metaKey) {
        event.preventDefault();
        handleCopy();
      }
      break;

    case 'v':
      // 粘贴 (Ctrl+V)
      if (event.ctrlKey || event.metaKey) {
        event.preventDefault();
        handlePaste();
      }
      break;

    case 'x':
      // 剪切 (Ctrl+X)
      if (event.ctrlKey || event.metaKey) {
        event.preventDefault();
        handleCut();
      }
      break;

    case 'z':
      // 撤销 (Ctrl+Z)
      if (event.ctrlKey || event.metaKey) {
        event.preventDefault();
        undo();
      }
      break;

    case 'y':
      // 重做 (Ctrl+Y)
      if (event.ctrlKey || event.metaKey) {
        event.preventDefault();
        redo();
      }
      break;

    default:
      // 其他键不做特殊处理
      break;
  }

  // 重置光标闪烁
  resetCursorBlink();
};

// 复制选中内容
const copySelection = () => {
  // 调用处理复制的函数
  handleCopy();
};

// 从剪贴板粘贴
const pasteFromClipboard = () => {
  // 调用处理粘贴的函数
  handlePaste();
};

// 导出简谱数据
const exportScore = () => {
  return pages.value;
};

// 加载内容
const loadContents = (data: any) => {
  if (data && Array.isArray(data)) {
    pages.value = data;
          saveHistory();
        }
};

// 保存内容
const saveContents = () => {
  return JSON.stringify(pages.value);
};

// 清理定时器函数
const cleanupTimers = () => {
  if (cursorBlinkInterval.value) {
    clearInterval(cursorBlinkInterval.value);
  }
};

// 插入音符符号功能
const insertNoteSymbol = (item: any) => {
  console.log('开始插入音符:', item.value);

  // 获取当前应该使用的音符区域的位置信息
  const { page, line } = currentLine.value;

  // 确保页面和行存在
  ensurePageAndLineExist(page, line);

  // 创建新的音符对象
  const newNote: MusicNote = {
    name: item.name || '',
    value: item.value,
    type: item.type,
    html: item.html || `<span class="music-symbol" data-note-type="${item.name}">${item.value}</span>`,
  };

  // 获取当前光标位置
  const noteIndex = cursorPosition.value.noteIndex;

  // 插入音符到数组中
  if (noteIndex === -1) {
    // 在行首插入
    pages.value[page].lines[line].notes.unshift(newNote);
    // 更新光标位置到新插入音符后
    cursorPosition.value.noteIndex = 0;
  } else if (noteIndex >= pages.value[page].lines[line].notes.length - 1) {
    // 在行末插入
    pages.value[page].lines[line].notes.push(newNote);
    // 更新光标位置到新插入音符后
    cursorPosition.value.noteIndex = pages.value[page].lines[line].notes.length - 1;
  } else {
    // 在音符中间插入
    pages.value[page].lines[line].notes.splice(noteIndex + 1, 0, newNote);
    // 更新光标位置
    cursorPosition.value.noteIndex = noteIndex + 1;
  }

  // 重置光标闪烁
  resetCursorBlink();

  // 聚焦到音符区域
  const noteArea = getNoteAreaElement(page, line);
  if (noteArea) {
    noteArea.focus();
    activeNoteArea.value = noteArea;
  }

  // 保存历史记录
  saveHistory();

  // 移除自动换行检查
  // checkAndAddNewLineIfFull(page, line);
};

// 检查并添加新行或页面（仅当行已满时）
const checkAndAddNewLineIfFull = (pageIndex: number, lineIndex: number) => {
  // 获取当前行的音符数量
  const currentLineNotes = pages.value[pageIndex].lines[lineIndex];

  // 判断音符是否已经超过一定数量（可自定义阈值）
  const MAX_NOTES_PER_LINE = 20; // 每行最多20个音符
  if (currentLineNotes.notes.length >= MAX_NOTES_PER_LINE) {
    // 是否是页面的最后一行
    const isLastLine = lineIndex === pages.value[pageIndex].lines.length - 1;

    // 判断页面是否已满（行数达到上限）
    const MAX_LINES_PER_PAGE = 10; // 每页最多10行
    const isPageFull = pages.value[pageIndex].lines.length >= MAX_LINES_PER_PAGE;

    if (isLastLine && isPageFull) {
      // 页面已满，添加新页面
      pages.value.push({
        lines: [
          {
            notes: [],
            lyric: '', // 改为空字符串而不是undefined
            lyricEditing: false,
          },
        ],
      });

      // 切换到新页面
      nextTick(() => {
        currentLine.value = { page: pageIndex + 1, line: 0 };

        // 设置光标位置
        cursorPosition.value = {
          page: pageIndex + 1,
          line: 0,
          noteIndex: -1,
          visible: true,
        };

        // 让新页面第一行获得焦点
        const newNoteArea = getNoteAreaElement(pageIndex + 1, 0);
        if (newNoteArea) {
          activeNoteArea.value = newNoteArea;
          newNoteArea.focus();
        }
      });
    } else {
      // 插入新行
      const newLineIndex = lineIndex + 1;

      // 检查新行是否需要创建
      if (newLineIndex >= pages.value[pageIndex].lines.length) {
        // 添加新行
        pages.value[pageIndex].lines.push({
          notes: [],
          lyric: '', // 改为空字符串而不是undefined
          lyricEditing: false,
        });
      } else {
        // 在指定位置插入新行
        pages.value[pageIndex].lines.splice(newLineIndex, 0, {
          notes: [],
          lyric: '', // 改为空字符串而不是undefined
          lyricEditing: false,
        });
      }

      // 切换到新行
      nextTick(() => {
        currentLine.value = { page: pageIndex, line: newLineIndex };

        // 设置光标位置
        cursorPosition.value = {
          page: pageIndex,
          line: newLineIndex,
          noteIndex: -1,
          visible: true,
        };

        // 让新行获得焦点
        const newNoteArea = getNoteAreaElement(pageIndex, newLineIndex);
        if (newNoteArea) {
          activeNoteArea.value = newNoteArea;
          newNoteArea.focus();
        }
      });
    }

    // 保存历史记录
  saveHistory();
  }
};

// 处理剪切操作
const handleCut = () => {
  // 如果没有选中内容，不进行任何操作
  if (!selection.value.active) {
    console.log('没有选中内容，无法剪切');
    return;
  }

  // 先复制选中内容
  handleCopy();

  // 然后删除选中内容
  deleteSelectedNotes();

  console.log('剪切操作完成');
};

// 撤销操作
const undo = () => {
  if (state.historyIndex > 0) {
    console.log('执行撤销操作，从索引', state.historyIndex, '到', state.historyIndex - 1);

    // 保存当前光标位置信息
    const prevCursorPosition = { ...cursorPosition.value };
    const { page, line, noteIndex } = prevCursorPosition;

    // 执行撤销
    state.historyIndex--;
    const editorState = JSON.parse(state.history[state.historyIndex]);

    // 更新页面数据
    pages.value = editorState;

    // 在DOM更新后尝试恢复光标位置
    nextTick(() => {
      // 确保恢复的页面和行存在
      if (pages.value[page] && pages.value[page].lines[line]) {
        // 检查恢复的noteIndex是否有效
        const maxNoteIndex = pages.value[page].lines[line].notes.length - 1;

        // 设置有效的光标位置
        cursorPosition.value = {
          page,
          line,
          // 如果之前的noteIndex超出了范围，则设置为最后一个音符或行首
          noteIndex: noteIndex > maxNoteIndex ? (maxNoteIndex >= 0 ? maxNoteIndex : -1) : noteIndex,
          visible: true,
        };

        // 更新当前行
        currentLine.value = { page, line };

        // 聚焦到音符区域
        const noteArea = getNoteAreaElement(page, line);
        if (noteArea) {
          noteArea.focus();
          activeNoteArea.value = noteArea;
        }
      } else {
        // 如果恢复的位置不存在，则设置到有效位置
        const lastPageIndex = pages.value.length - 1;
        if (lastPageIndex >= 0) {
          const lastLineIndex = pages.value[lastPageIndex].lines.length - 1;
          if (lastLineIndex >= 0) {
            cursorPosition.value = {
              page: lastPageIndex,
              line: lastLineIndex,
              noteIndex: -1,
              visible: true,
            };

            // 更新当前行
            currentLine.value = { page: lastPageIndex, line: lastLineIndex };

            // 聚焦到音符区域
            const noteArea = getNoteAreaElement(lastPageIndex, lastLineIndex);
            if (noteArea) {
              noteArea.focus();
              activeNoteArea.value = noteArea;
            }
          }
        }
      }
    });
  } else {
    console.log('已经是最早的历史记录，无法继续撤销');
  }
};

// 重做操作
const redo = () => {
  if (state.historyIndex < state.history.length - 1) {
    console.log('执行重做操作，从索引', state.historyIndex, '到', state.historyIndex + 1);

    // 保存当前光标位置信息
    const prevCursorPosition = { ...cursorPosition.value };
    const { page, line, noteIndex } = prevCursorPosition;

    // 执行重做
    state.historyIndex++;
    const editorState = JSON.parse(state.history[state.historyIndex]);

    // 更新页面数据
    pages.value = editorState;

    // 在DOM更新后尝试恢复光标位置
    nextTick(() => {
      // 确保恢复的页面和行存在
      if (pages.value[page] && pages.value[page].lines[line]) {
        // 检查恢复的noteIndex是否有效
        const maxNoteIndex = pages.value[page].lines[line].notes.length - 1;

        // 设置有效的光标位置
        cursorPosition.value = {
          page,
          line,
          // 如果之前的noteIndex超出了范围，则设置为最后一个音符或行首
          noteIndex: noteIndex > maxNoteIndex ? (maxNoteIndex >= 0 ? maxNoteIndex : -1) : noteIndex,
          visible: true,
        };

        // 更新当前行
        currentLine.value = { page, line };

        // 聚焦到音符区域
        const noteArea = getNoteAreaElement(page, line);
        if (noteArea) {
          noteArea.focus();
          activeNoteArea.value = noteArea;
        }
      } else {
        // 如果恢复的位置不存在，则设置到有效位置
        const lastPageIndex = pages.value.length - 1;
        if (lastPageIndex >= 0) {
          const lastLineIndex = pages.value[lastPageIndex].lines.length - 1;
          if (lastLineIndex >= 0) {
            cursorPosition.value = {
              page: lastPageIndex,
              line: lastLineIndex,
              noteIndex: -1,
              visible: true,
            };

            // 更新当前行
            currentLine.value = { page: lastPageIndex, line: lastLineIndex };

            // 聚焦到音符区域
            const noteArea = getNoteAreaElement(lastPageIndex, lastLineIndex);
            if (noteArea) {
              noteArea.focus();
              activeNoteArea.value = noteArea;
            }
          }
        }
      }
    });
  } else {
    console.log('已经是最新的历史记录，无法继续重做');
  }
};

// 处理歌词输入获得焦点
const handleLyricInputFocus = (event: FocusEvent, pageIndex: number, lineIndex: number) => {
  console.log('歌词输入框获得焦点');

  // 移除音符区域的焦点和活动状态
  const noteArea = getNoteAreaElement(pageIndex, lineIndex);
  if (noteArea) {
    noteArea.blur();
    console.log('确保音符区域失去焦点');

    // 隐藏光标并暂停光标闪烁
    cursorPosition.value.visible = false;
    if (cursorBlinkInterval.value) {
      clearInterval(cursorBlinkInterval.value);
      cursorBlinkInterval.value = null;
    }
  }

  // 阻止事件冒泡，避免触发其他焦点事件
  event.stopPropagation();
};

// 处理歌词点击进入编辑模式 - 需要处理el-input的焦点
const enterLyricEditMode = (pageIndex: number, lineIndex: number, event?: MouseEvent) => {
  // 阻止事件冒泡，防止触发音符区域的点击事件
  if (event) {
    event.stopPropagation();
    event.preventDefault();
  }

  console.log('进入歌词编辑模式:', pageIndex, lineIndex);

  // 设置为编辑模式
  pages.value[pageIndex].lines[lineIndex].lyricEditing = true;

  // 强制移除音符区域的焦点
  const noteArea = getNoteAreaElement(pageIndex, lineIndex);
  if (noteArea) {
    noteArea.blur();
    console.log('已移除音符区域的焦点');

    // 同时隐藏光标
    cursorPosition.value.visible = false;
  }

  // 将焦点移动到页面文档，然后再移动到输入框，确保音符区域完全失去焦点
  document.body.focus();

  // 下一个周期聚焦到输入框
  nextTick(() => {
    const input = getLyricInputElement(pageIndex, lineIndex);
    if (input) {
      input.focus();
      console.log('已聚焦到歌词输入框');
    } else {
      console.log('未找到歌词输入框');
    }
  });
};

// 声明要暴露的函数和变量
defineExpose({
  exportScore,
  undo,
  redo,
  saveContents,
  loadContents,
  insertNoteSymbol,
  addNewPage,
  addLyricLine,
  copySelection,
  pasteFromClipboard,
  handleNoteFocus,
  handleNoteBlur,
  handleNoteClick,
  handleKeyDown,
  handleLyricInputBlur,
  handleLyricInputFocus,
  enterLyricEditMode,
  alignMode,
  setAlignMode,
  zoom,
  zoomIn,
  zoomOut,
  resetZoom,
});
</script>

<script lang="ts">
export default {
  name: 'ScoreEditor',
};
</script>

<style scoped>
:root {
  --top-offset: 0px; /* 将在mounted中计算 */
}

.editor-container {
  display: flex;
  width: 100%;
  height: calc(100vh - var(--top-offset));
  max-height: calc(100vh - var(--top-offset));
  overflow: hidden;
  position: relative;
}

.editor-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  height: 100%;
  max-height: 100%;
  overflow: hidden;
}

.top-toolbar {
  display: flex;
  gap: 15px;
  padding: 8px 15px;
  background-color: #f0f0f0;
  border-bottom: 1px solid #ddd;
  z-index: 100;
  align-items: center;
  flex-shrink: 0;
}

.bottom-status-bar {
  padding: 6px 15px;
  background-color: #f0f0f0;
  border-top: 1px solid #ddd;
  z-index: 100;
  font-size: 12px;
  color: #666;
  flex-shrink: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.zoom-info,
.page-info {
  font-size: 13px;
  color: #555;
  margin: 0 5px;
}

.editor-scroll-container {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  background-color: #e0e0e0;
  padding: 20px;
  display: flex;
  justify-content: center;
}

.editor-zoom-container {
  transform-origin: top center;
  padding: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  height: fit-content;
}

/* 设置A4纸张尺寸 */
.page-container {
  width: 210mm; /* A4宽度 */
  min-height: 297mm; /* A4高度 */
  background-color: white;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  margin-bottom: 20mm;
  position: relative;
  box-sizing: border-box;
  padding: 20px;
}

.line-container {
  display: flex;
  margin-bottom: 15px;
  align-items: stretch;
}

.note-area {
  flex: 1;
  min-height: 50px;
  border: 1px solid #ddd;
  padding: 10px;
  border-radius: 4px;
  outline: none;
  transition: border-color 0.2s;
  position: relative;
}

.note-area.active {
  border-color: #3498db;
  box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.3);
}

.note-area.no-text-input {
  cursor: default;
}

.note-area.no-text-input::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 0;
}

.notes-container {
  position: relative;
  min-height: 30px;
  font-family: 'MusicFont', sans-serif; /* 使用音符字体 */
  font-size: 24px;
  display: flex;
  flex-wrap: nowrap; /* 防止换行 */
  align-items: center;
  overflow-x: auto; /* 当内容溢出时显示水平滚动条 */
}

/* 左对齐模式（默认） */
.notes-container {
  justify-content: flex-start;
}

/* 两端对齐模式 */
.notes-container.notes-justify {
  justify-content: space-between;
}

/* 两端对齐且音符较多时，使用更紧凑的分布 */
.notes-container.notes-justify:has(.note-span:nth-child(n + 10)) {
  justify-content: space-evenly; /* 均匀分布 */
}

/* 两端对齐但音符不多时，避免过度拉伸 */
.notes-container.notes-justify:has(.note-span:only-child),
.notes-container.notes-justify:has(.note-span:nth-child(2):nth-last-child(1)),
.notes-container.notes-justify:has(.note-span:nth-child(3):nth-last-child(1)) {
  justify-content: flex-start;
}

/* 增强音符与歌词的对应关系 */
.notes-container.notes-justify + .lyric-container .lyric-display {
  display: flex;
  justify-content: space-between;
  padding-right: 28px; /* 为删除按钮留出空间 */
}

.notes-container:not(.notes-justify) + .lyric-container .lyric-display {
  text-align: left;
  text-align-last: left;
  justify-content: flex-start;
}

.empty-placeholder {
  color: #888;
  font-style: italic;
  user-select: none;
  pointer-events: none;
  width: 100%;
}

.note-span {
  display: inline-block;
  position: relative;
  font-family: 'MusicFont', sans-serif; /* 确保音符字体应用到单个音符 */
  margin: 0 2px;
  white-space: nowrap; /* 防止音符内部换行 */
  min-width: 1em; /* 保证最小宽度 */
}

/* 根据音符数量动态调整间距 */
.notes-container:has(.note-span:nth-child(n + 15)) .note-span {
  margin: 0 1px; /* 音符较多时减小间距 */
}

.notes-container:has(.note-span:nth-child(n + 25)) .note-span {
  margin: 0; /* 音符非常多时移除间距 */
}

.note-span.selected {
  background-color: rgba(52, 152, 219, 0.2);
}

.virtual-cursor {
  display: inline-block;
  width: 2px;
  height: 20px;
  background-color: #3498db;
  vertical-align: middle;
  animation: blink 1s step-end infinite;
}

/* 歌词样式 */
.lyric-container {
  margin-top: 10px;
  padding-top: 5px;
  border-top: 1px dashed #ddd;
  position: relative;
}

.lyric-display-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* 歌词两端对齐模式 */
.lyric-display-container.lyric-justify .lyric-display {
  text-align: justify;
  text-align-last: justify;
  letter-spacing: 0.05em; /* 增加字间距，使文本更容易对齐 */
}

/* 歌词较短时避免过度拉伸 */
.lyric-display-container.lyric-justify .lyric-display:empty,
.lyric-display-container.lyric-justify .lyric-display:only-child {
  text-align: left;
  text-align-last: left;
}

.lyric-display {
  flex: 1;
  font-size: 16px;
  color: #555;
  min-height: 24px;
  padding: 4px;
  cursor: pointer;
  border-radius: 4px;
  transition: background-color 0.2s;
  white-space: pre; /* 保留空格，确保字符间距与编辑时一致 */
  position: relative; /* 用于精确定位歌词字符 */
}

.lyric-display:hover {
  background-color: #f5f5f5;
}

.lyric-display:empty::before {
  content: '点击添加歌词';
  color: #aaa;
  font-style: italic;
}

.lyric-input-container {
  width: 100%;
}

.lyric-input {
  width: 100%;
  padding: 4px 8px;
  font-size: 16px;
  border: 1px solid #3498db;
  border-radius: 4px;
  outline: none;
  box-sizing: border-box;
}

.lyric-delete-btn {
  background: none;
  border: none;
  font-size: 16px;
  color: #999;
  cursor: pointer;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s, color 0.2s;
}

.lyric-delete-btn:hover {
  background-color: #ff4d4f;
  color: white;
}

@keyframes blink {
  from,
  to {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

/* 确保左侧菜单和右侧编辑区高度一致 */
:deep(.make-score-container) {
  height: 100%;
  max-height: calc(100vh - var(--top-offset));
  overflow-y: auto;
}

/* 当字符数量较多时，减小内部字符间距 */
.notes-container:has(.note-span:nth-child(n + 15)) + .lyric-container .lyric-display {
  letter-spacing: -0.05em;
}

/* 当字符数量非常多时，进一步减小内部字符间距 */
.notes-container:has(.note-span:nth-child(n + 25)) + .lyric-container .lyric-display {
  letter-spacing: -0.1em;
  font-size: 14px; /* 稍微减小字体大小 */
}

.corner-zoom-controls {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-left: auto;
}

.zoom-btn {
  background: none;
  border: none;
  font-size: 16px;
  color: #999;
  cursor: pointer;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s, color 0.2s;
}

.zoom-btn:hover {
  background-color: #3498db;
  color: white;
}

.zoom-value {
  font-size: 14px;
  color: #555;
  cursor: pointer;
  padding: 0 5px;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.zoom-value:hover {
  background-color: #e6e6e6;
}

.reset-zoom-btn {
  font-size: 13px;
  color: #666;
  background-color: #e6e6e6;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 2px 6px;
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s;
  margin-left: 8px;
}

.reset-zoom-btn:hover {
  background-color: #3498db;
  color: white;
  border-color: #3498db;
}
</style>
